package com.study.manage.mvc.v2;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.study.manage.dal.BlogBuyRepository;
import com.study.manage.dal.BlogCommentRepository;
import com.study.manage.dal.BlogMediaRepository;
import com.study.manage.dal.BlogRepository;
import com.study.manage.dal.BlogStatDayRepository;
import com.study.manage.dal.EvaluateNewRepository;
import com.study.manage.dal.EvaluateRepository;
import com.study.manage.dal.MediaRepository;
import com.study.manage.dal.NewsRepository;
import com.study.manage.domain.Blog;
import com.study.manage.domain.BlogMedia;
import com.study.manage.domain.Evaluate;
import com.study.manage.domain.EvaluateNew;
import com.study.manage.domain.Media;
import com.study.manage.domain.News;
import com.study.manage.domain.enumm.BlogStatDayType;
import com.study.manage.domain.enumm.BlogType;
import com.study.manage.domain.enumm.EvaluateNewType;
import com.study.manage.domain.enumm.LiveDieState;
import com.study.manage.domain.enumm.MediaType;
import com.study.manage.dto.AjaxResponse;
import com.study.manage.dto.SessionUser;
import com.study.manage.mvc.common.UploadController;
import com.study.manage.utils.MapUtils;


@Controller
@RequestMapping("/v2/shop")
public class V2ShopController extends UploadController {


    @RequestMapping(path = "article", method = RequestMethod.GET)
    public String article(HttpServletRequest request, ModelMap model,
            HttpServletResponse response) {
        return "v2/shop/article";
    }

    @RequestMapping(path = "notice", method = RequestMethod.GET)
    public String notice(HttpServletRequest request, ModelMap model, HttpServletResponse response) {
        return "v2/shop/notice";
    }

    @RequestMapping(path = "zpq", method = RequestMethod.GET)
    public String zpq(HttpServletRequest request, ModelMap model, HttpServletResponse response) {
        return "v2/shop/zpq";
    }


    @RequestMapping(path = "new", method = RequestMethod.GET)
    public String news(HttpServletRequest request, ModelMap model, HttpServletResponse response) {
        return "v2/shop/new";
    }

    @Autowired
    private EvaluateNewRepository evaluateNewRepository;
    @Autowired
    private BlogRepository blogRepository;
    @Autowired
    private BlogStatDayRepository blogStatDayRepository;
    @Autowired
    private BlogCommentRepository blogCommentRepository;
    @Autowired
    private BlogBuyRepository blogBuyRepository;
    @Autowired
    private EvaluateRepository evaluateRepository;
    @Autowired
    private BlogMediaRepository blogMediaRepository;
    @Autowired
    private NewsRepository newsRepository;

    @ResponseBody
    @RequestMapping(path = "article-list", method = RequestMethod.GET)
    public AjaxResponse articleList(HttpServletRequest request, Long evaluateId,
            @PageableDefault(sort = {"createdAt"}, direction = Direction.DESC) Pageable pageable) {
        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = getUserInfo();
        Page<News> page = null;
        if (evaluateId == null) {
            page = newsRepository.findByTypeInAndUserId(Arrays.asList(EvaluateNewType.ZT),
                    su.getId(), pageable);
        } else {
            page = newsRepository.findByTypeInAndUserIdAndEvaluateId(
                    Arrays.asList(EvaluateNewType.ZT), su.getId(), evaluateId, pageable);
        }
        return ajax.setObj(page.map(new Converter<News, Map<String, Object>>() {
            @Override
            public Map<String, Object> convert(News source) {
                Blog blog = blogRepository.findOne(source.blogId);
                Map<String, Object> map = MapUtils.convert(blog);
                map.put("coverUrl", blogMediaRepository.findOneImgUrlByBlogId(blog.id));
                map.put("lookCount", blogStatDayRepository.sumCountByBlogIdAndTypeAndDate(blog.id,
                        BlogStatDayType.Look, null));
                map.put("openCount", blogStatDayRepository.sumCountByBlogIdAndTypeAndDate(blog.id,
                        BlogStatDayType.Open, null));
                map.put("commentCount",
                        blogCommentRepository.countByBlogIdAndState(blog.id, LiveDieState.LIVE));
                map.put("buyCount", blogBuyRepository.countByBlogIdAndPay(blog.id));

                List<Map<String, Object>> lists = new ArrayList<>();

                List<EvaluateNew> ens =
                        evaluateNewRepository.findByBlogIdAndState(blog.id, LiveDieState.LIVE);
                for (EvaluateNew en : ens) {
                    Evaluate e = evaluateRepository.findOne(en.evaluateId);
                    lists.add(MapUtils.convert(e, "coverUrl", "id", "title", "createdAt"));
                }

                map.put("evaluateList", lists);
                return map;
            }

        }));
    }

    @ResponseBody
    @RequestMapping(path = "article-del", method = RequestMethod.POST)
    public AjaxResponse articleDel(HttpServletRequest request, Long id, LiveDieState state,
            @PageableDefault(sort = {"createdAt"}, direction = Direction.DESC) Pageable pageable) {
        AjaxResponse ajax = new AjaxResponse(true);
        Blog en = blogRepository.findOne(id);
        en.state = state;
        blogRepository.save(en);
        return ajax;
    }


    @RequestMapping(path = "article-detail", method = RequestMethod.GET)
    public String articleDetail(HttpServletRequest request, Long id, ModelMap model,
            HttpServletResponse response) {
        Map<String, Object> map = null;
        if (id != null) {
            Blog b = blogRepository.findOne(id);
            map = MapUtils.convert(b);
            map.put("coverUrl", blogMediaRepository.findOneImgUrlByBlogId(b.id));
            List<EvaluateNew> ens =
                    evaluateNewRepository.findByBlogIdAndState(b.id, LiveDieState.LIVE);
            List<Long> ids = new ArrayList<>();
            for (EvaluateNew en : ens) {
                ids.add(en.evaluateId);
            }
            map.put("evaluateIds", jsonMapper.toJson(ids));
        } else {
            map = MapUtils.convert(new Blog());
            map.put("coverUrl", null);
            map.put("evaluateIds", "[]");
        }
        model.put("data", map);
        return "v2/shop/article-detail";
    }

    @ResponseBody
    @RequestMapping(path = "article-evaluate", method = RequestMethod.GET)
    public AjaxResponse articleEvaluate(HttpServletRequest request, String evaluateIds,
            HttpServletResponse response) {
        AjaxResponse ajax = new AjaxResponse(true);
        List<Object> eids = jsonMapper.fromJson(evaluateIds, List.class);
        List<Map<String, Object>> lists = new ArrayList<>();
        for (Object id : eids) {
            Evaluate e = evaluateRepository.findOne(Long.valueOf(id.toString()));
            lists.add(MapUtils.convert(e, "coverUrl", "id", "title", "createdAt"));
        }
        return ajax.setObj(lists);
    }

    @Autowired
    private MediaRepository mediaRepository;

    @Transactional
    @ResponseBody
    @RequestMapping(path = "article-detailSave", method = RequestMethod.POST)
    public AjaxResponse articleDetailSave(HttpServletRequest request, String coverUrl, Float price,
            Float price2, Long id, Long[] evaluateIds, HttpServletResponse response) {
        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = getUserInfo();
        Blog blog = null;
        if (id == null) {
            blog = new Blog();
            blog.userId = su.getId();
            blog.type = BlogType.AdminZhuanTi;
            blog.extId = 1l;
        } else {
            blog = blogRepository.findOne(id);
        }

        MapUtils.copyProperties(blog, this.getRequestParameter(request));
        blog.price = price;
        blog.price2 = price2;
        blogRepository.save(blog);

        List<News> news = newsRepository.findByBlogId(blog.id);
        News n = null;;
        if (news.isEmpty()) {
            n = new News();
        } else {
            n = news.get(0);
        }
        n.userId = su.getId();
        n.blogId = blog.id;
        n.pic = coverUrl;
        n.title = blog.title;
        n.type = EvaluateNewType.ZT;
        n.state = LiveDieState.LIVE;
        newsRepository.save(n);

        if (!StringUtils.isEmpty(coverUrl)) {
            String mediaUrl = blogMediaRepository.findOneImgUrlByBlogId(blog.id);
            if (mediaUrl == null || !coverUrl.equals(mediaUrl)) {
                blogMediaRepository.updateStateByBlogId(blog.id);
                Media media = new Media();
                media.url = coverUrl;
                media.type = MediaType.PIC;
                mediaRepository.save(media);
                BlogMedia bm = new BlogMedia();
                bm.blogId = blog.id;
                bm.mediaId = media.id;
                blogMediaRepository.save(bm);
            }

        }

        evaluateNewRepository.deleteByNewsId(n.id);
        if (evaluateIds != null) {
            for (Long evaluateId : evaluateIds) {
                List<EvaluateNew> ens =
                        evaluateNewRepository.findByEvaluateIdAndNewsId(evaluateId, n.id);
                EvaluateNew en = null;
                if (!ens.isEmpty()) {
                    en = ens.get(0);
                } else {
                    en = new EvaluateNew();
                    en.evaluateId = evaluateId;
                    en.newsId = n.id;
                }
                en.state = LiveDieState.LIVE;
                evaluateNewRepository.save(en);
            }
        }
        return ajax;
    }



    @ResponseBody
    @RequestMapping(path = "notice-list", method = RequestMethod.GET)
    public AjaxResponse noticeList(HttpServletRequest request,
            @RequestParam(defaultValue = "NOTICE") EvaluateNewType type,
            @RequestParam(defaultValue = "LIVE") LiveDieState state,
            @PageableDefault(sort = {"createdAt"}, direction = Direction.DESC) Pageable pageable) {
        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = this.getUserInfo();
        Page<News> page =
                newsRepository.findByTypeInAndUserId(Arrays.asList(type), su.getId(), pageable);
        return ajax.setObj(page.map(new Converter<News, Map<String, Object>>() {
            @Override
            public Map<String, Object> convert(News source) {
                Map<String, Object> map = MapUtils.convert(source);
                List<EvaluateNew> ens =
                        evaluateNewRepository.findByNewsIdAndState(source.id, LiveDieState.LIVE);
                List<Map<String, Object>> lists = new ArrayList<>();
                for (EvaluateNew en : ens) {
                    Evaluate e = evaluateRepository.findOne(en.evaluateId);
                    lists.add(MapUtils.convert(e, "coverUrl", "id", "title", "createdAt"));
                }
                map.put("evaluateList", lists);
                return map;
            }
        }));
    }



    @RequestMapping(path = "notice-detail", method = RequestMethod.GET)
    public String noticeDetail(HttpServletRequest request,
            @RequestParam(defaultValue = "NOTICE") EvaluateNewType type, Long id, ModelMap model,
            HttpServletResponse response) {
        Map<String, Object> map = null;
        if (id != null) {
            News b = newsRepository.findOne(id);
            type = b.type;
            map = MapUtils.convert(b);
            List<EvaluateNew> ens =
                    evaluateNewRepository.findByNewsIdAndState(b.id, LiveDieState.LIVE);
            List<Long> ids = new ArrayList<>();
            for (EvaluateNew en : ens) {
                ids.add(en.evaluateId);
            }
            map.put("evaluateIds", jsonMapper.toJson(ids));
        } else {
            map = MapUtils.convert(new News());
            map.put("type", type);
            map.put("evaluateIds", "[]");
        }
        model.put("data", map);
        if (type.equals(EvaluateNewType.NOTICE)) {
            return "v2/shop/notice-detail";
        } else if (type.equals(EvaluateNewType.ZPQ)) {
            return "v2/shop/zpq-detail";
        } else if (type.equals(EvaluateNewType.NEW)) {
            return "v2/shop/new-detail";
        }
        return "v2/shop/notice-detail";
    }

    @ResponseBody
    @RequestMapping(path = "notice-del", method = RequestMethod.POST)
    public AjaxResponse noticeDel(HttpServletRequest request, Long id, LiveDieState state) {
        AjaxResponse ajax = new AjaxResponse(true);
        News en = newsRepository.findOne(id);
        en.state = state;
        newsRepository.save(en);
        return ajax;
    }


    @Transactional
    @ResponseBody
    @RequestMapping(path = "notice-detailSave", method = RequestMethod.POST)
    public AjaxResponse noticeDetailSave(HttpServletRequest request, Long[] evaluateIds,
            String contentImgJson, Long id, HttpServletResponse response) {
        AjaxResponse ajax = new AjaxResponse(true);
        SessionUser su = this.getUserInfo();
        News news = null;
        if (id != null) {
            news = newsRepository.findOne(id);
        } else {
            news = new News();
            news.userId = su.getId();
        }
        MapUtils.copyObj(this.getRequestParameter(request), news, "id");
        if (!StringUtils.isEmpty(contentImgJson)) {
            news.contentImg = contentImgJson;
        }
        newsRepository.save(news);

        evaluateNewRepository.deleteByNewsId(news.id);
        if (evaluateIds != null) {
            for (Long evaluateId : evaluateIds) {
                List<EvaluateNew> ens =
                        evaluateNewRepository.findByEvaluateIdAndNewsId(evaluateId, news.id);
                EvaluateNew en = null;
                if (!ens.isEmpty()) {
                    en = ens.get(0);
                } else {
                    en = new EvaluateNew();
                    en.newsId = id;
                    en.evaluateId = evaluateId;
                }
                en.state = LiveDieState.LIVE;
                evaluateNewRepository.save(en);
            }
        }
        return ajax;
    }
}
